package cn.sc.summer.token.encrypt;

import cn.sc.summer.constant.encrypt.EncryptKeyConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.SecureRandom;

/**
 * DES加密介绍 DES是一种对称加密算法，所谓对称加密算法即：加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究，
 * 后来被美国政府正式采用，之后开始广泛流传，但是近些年使用越来越少，因为DES使用56位密钥，以现代计算能力，
 * 24小时内即可被破解。虽然如此，在某些简单应用中，我们还是可以使用DES加密算法，本文简单讲解DES的JAVA实现 。
 * 注意：DES加密和解密过程中，密钥长度都必须是8的倍数
 */
@Slf4j
@Component
public class DesUtil {

    /**
     * DES加密
     *
     * @param encryptStr 需要加密字符串
     * @return byte[]
     */
    public static String encrypt(String encryptStr) {
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(EncryptKeyConstant.DES_SECURE_KEY.getBytes());
            // 创建一个密匙工厂，然后用它把DESKeySpec转换成
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey securekey = keyFactory.generateSecret(desKey);
            // Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("DES");
            // 用密匙初始化Cipher对象,ENCRYPT_MODE用于将 Cipher 初始化为加密模式的常量
            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
            // 现在，获取数据并加密
            // 正式执行加密操作
            byte[] enc = cipher.doFinal(encryptStr.getBytes("UTF8"));
            // Encode bytes to base64 to get a string
            return new sun.misc.BASE64Encoder().encode(enc);
            //return cipher.doFinal(datasource); // 按单部分操作加密或解密数据，或者结束一个多部分操作
        } catch (Exception e) {
            throw new RuntimeException("DES encrypt exception:" + e.getMessage(), e);
        }
    }

    /**
     * DES解密
     *
     * @param decryptStr 解密字符串
     * @return byte[]
     * @throws Exception
     */
    public static String decrypt(String decryptStr) {
        try {
            byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(decryptStr);
            // DES算法要求有一个可信任的随机数源
            SecureRandom random = new SecureRandom();
            // 创建一个DESKeySpec对象
            DESKeySpec desKey = new DESKeySpec(EncryptKeyConstant.DES_SECURE_KEY.getBytes());
            // 创建一个密匙工厂
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 返回实现指定转换的
            // Cipher 对象
            // 将DESKeySpec对象转换成SecretKey对象
            SecretKey securekey = keyFactory.generateSecret(desKey);
            // Cipher对象实际完成解密操作
            Cipher cipher = Cipher.getInstance("DES");
            // 用密匙初始化Cipher对象
            cipher.init(Cipher.DECRYPT_MODE, securekey, random);
            // 真正开始解密操作
            byte[] bytes = cipher.doFinal(dec);
            return new String(bytes, "UTF8");
        } catch (Exception e) {
            throw new RuntimeException("DES decrypt exception:" + e.getMessage(), e);
        }
    }

}
